import java.io.Serializable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

/** This class stores the address where a socket is listening,
 * including the ip address and the port number.
 * @author danielkaufman 
 * @author matthewPolk
 */
@SuppressWarnings("serial")
public class Address implements Serializable, Comparable<Address> {
	private int id;
	private int port;
	private String ip;
	
	/** Constructs a new Address with the specified ip, port, and id
	 * @param _ip the String representation of the ip address
	 * @param _port the number of the port to listen to
	 * @param _id the id of the process listening on this address
	 */
	public Address(String _ip, int _port, int _id){
		ip = _ip;
		id = _id;
		port = _port;
	}
	
	/** Constructs a new Address with the specified ip, port, and id
	 * @param ina the InetAddress representation of the ip address
	 * @param _port the number of the port to listen to
	 * @param _id the id of the process listening on this address
	 */
	public Address(InetAddress ina, int _port, int _id){
		id = _id;
		ip = ina.getHostAddress();
		port = _port;
	}
	
	/** Constructs a new Address with the specified ip, port, and id
	 * @param insa the InetSocketAddress representation of the ip address and port number
	 * @param _id the id of the process listening on this address
	 */
	public Address(InetSocketAddress insa, int _id){
		id = _id;
		ip = insa.getHostName();
		port = insa.getPort();
	}
	
	/*
	 * (non-Javadoc)
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	public int compareTo(Address o) {
		// return (new Integer(id).compareTo(new Integer(o.id)));
		int result = id - o.id;
		if (result > 0) { return 1; }
		else if (result < 0) { return -1; }
		else { return 0; }
	}
	
	/** The id for this address
	 * @return the integer ID for this address
	 */
	public int getID(){
		return id;
	}
	
	/** the port component of this address
	 * @return the port number of this address
	 */
	public int getPort(){
		return port;
	}
	
	/**Returns the String representation of the IP address corresponding to this Address.
	 * @return the String representation of this IP Address.
	 */
	public String getStringIP(){
		return ip;
	}
	
	/**Accesses the InetAddress for this node.
	 * 
	 * @return The InetAddress used to speak with this node.
	 * @throws UnknownHostException if the ip is not a legitimate IP Address. 
	 */
	public InetAddress getInet() throws UnknownHostException{
		return (InetAddress.getByName(ip));
	}
	
	/**Returns the IP address and port as an InetSocket Address.
	 * 
	 * @return the ip address and port number as an InetSocketAddress.
	 */
	public InetSocketAddress getInetSocket(){
		return (InetSocketAddress.createUnresolved(ip, port));
	}
	/**Mutator method to set the id for this node.
	 * 
	 * @param _id The new id number.
	 */
	public void setID(int _id){
		id = _id;
	}
	
	/**Mutator method to set the ip address for this node.
	 * 
	 * @param _ip The new ip address.
	 */
	public void setIP(String _ip){
		ip = new String(ip);
	}
	
	/**Mutator method to set the port number for this node.
	 * 
	 * @param _port The new port number.
	 */
	public void setPort(int _port){
		port = _port;
	}
	
	public boolean compareTo(Object o){
		try {
			Address other = (Address)o;
			return ((ip == other.ip) && (port == other.port) && ip.equals(other.ip));
		}
		catch (ClassCastException e){
			return false;
		}
	}
	
	public String toString(){
		return ("ID: " + id + ", IP: " + ip + ", Port: " + port);
	}
}
